package com.zh.demo.tabula;

// import com.aspose.pdf.Page;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import org.springframework.util.CollectionUtils;
import technology.tabula.*;
import technology.tabula.extractors.BasicExtractionAlgorithm;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 利用PDFBox + tabula读取pdf文件
 * 原理 通过定位 “通行记录明细” 和 “停车记录明细” 两个表格位置来读取表格，并对内容进行分类
 */
public class ReadTableByLimitFromPdf {


    static String filePath = "C:\\Users\\zhjx2\\Documents\\卡号1_停车记录有边框.pdf";

    /**
     * 要实现的目标为：
     * 1. 解析 “通行记录明细” 至 “停车记录明细” 之间的表格内容，记录为 通行明细
     * 2. 解析 “停车记录明细” 至 “其他” 之间的表格内容，记录为 停车明细
     * @param args
     */
    public static void main(String[] args) {

        ReadTableByLimitFromPdf readTableByLimitFromPdf = new ReadTableByLimitFromPdf();
        //创建文档对象
        PDDocument doc =null;
        String content="";
        try {


            //加载一个pdf对象
            doc =PDDocument.load(new File(filePath));
            // 获取"通行记录明细"表格开始位置坐标
            BorderLimit startLimit = readTableByLimitFromPdf.findKeyPosition(doc, "通行记录明细");
            // 获取"通行记录明细"表格结束位置坐标
            BorderLimit endLimit = readTableByLimitFromPdf.findKeyPosition(doc, "停车记录明细");

            // 读取表格内容
            readTableByLimitFromPdf.readPassageStatement(doc);

            //关闭文档
            doc.close();

            System.out.println(String.format("开始坐标：页码%s;y坐标：%s",startLimit.getPageNum(),startLimit.getY()));
            System.out.println(String.format("结束坐标：页码%s;y坐标：%s",endLimit.getPageNum(),endLimit.getY()));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取 startKey 关键字在文档中Y 坐标 和所在页码 作为表格边界标记
     * @param doc
     * @param key
     * @return
     */
    private BorderLimit findKeyPosition(PDDocument doc,String key){
        BorderLimit borderLimit = new BorderLimit();
        try {
            //获取一个PDFTextStripper文本剥离对象
            PDFTextStripperExtractor stripper = new PDFTextStripperExtractor();
            stripper.setSortByPosition(true);

            stripper.setKeyText(key);


            // 遍历所有页面，提取关键词位置
            for (int pageNum = 0; pageNum < doc.getNumberOfPages(); pageNum++) {
                stripper.setStartPage(pageNum + 1);
                stripper.setEndPage(pageNum + 1);
                stripper.getText(doc);

                // 输出当前页找到的关键词坐标
                System.out.println("在第 " + (pageNum + 1) + " 页找到关键词："+ key);
                if (!CollectionUtils.isEmpty(stripper.getKeywordPositions())) {
                    borderLimit.setPageNum(pageNum+1);
                    borderLimit.setY(stripper.getKeywordPositions().get(0));
                    // 文档中“通行记录明细”唯一存在，找到后可提前退出
                    return borderLimit;
                }

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }


    /**
     * 读取通行记录明细
     * @param doc
     */
    public void readPassageStatement(PDDocument doc){
        try {

            ObjectExtractor extractor = new ObjectExtractor(doc);

            for (int pageNum = 0; pageNum < doc.getNumberOfPages(); pageNum++){
                Page page = extractor.extract(pageNum+1);
//                Rectangle rect = new Rectangle(0, 0, 595, 842); // A4纸张大小
                BasicExtractionAlgorithm bea = new BasicExtractionAlgorithm();
                List<Table> tables = bea.extract(page);

                for (Table table : tables) {
                    System.out.println(String.format("页码：%s;table y: %s",(pageNum+1),table.getCenterY()));
                    for (List<RectangularTextContainer> row : table.getRows()) {
                        for (RectangularTextContainer cell : row) {
                            System.out.print(""+cell.getY()+"---"+cell.getText(false) + "\t");
                        }
                        System.out.println();
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
